﻿#include "filepathutils.h"

#include <QDebug>
#include <QString>
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QTextStream>

namespace Common {

	const QString BACKUP_FILE_SUFFIX = ".bak";

	FilePathUtils::FilePathUtils(QObject *parent)
		: QObject(parent)
	{

	}

	FilePathUtils::~FilePathUtils()
	{

	}

	bool FilePathUtils::isExist(QString path)
	{
		path.replace("/", "\\");
		QFileInfo fileInfo(path);
		if (fileInfo.isDir() || fileInfo.isFile())
		{
			return true;
		}
		return false;
	}

	bool FilePathUtils::isExistFile(QString path)
	{
		path.replace("/", "\\");
		QFileInfo fileInfo(path);
		return fileInfo.isFile();
	}

	bool FilePathUtils::isExistDir(QString path)
	{
		path.replace("/", "\\");
		QFileInfo dir(path);
		return dir.isDir();
	}

	bool FilePathUtils::isRoot(QString path)
	{
		path.replace("/", "\\");
		QFileInfo fileInfo(path);
		if (fileInfo.isDir())
		{
			return  fileInfo.dir().isRoot();
		}
		return false;
	}

	bool FilePathUtils::isEmpty(QString path)
	{
		path.replace("/", "\\");
		QFileInfo fileInfo(path);
		if (fileInfo.isDir())
		{
			QDir dir(path);
			dir.setFilter(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
			QFileInfoList fileList = dir.entryInfoList();

			if (fileList.size() <= 0)
			{
				return true;
			}
		}
		else if (fileInfo.isFile())
		{
			QFile file(path);
			if (file.size() <= 0)
			{
				return true;
			}
		}
		return false;
	}

	bool FilePathUtils::removeDir(QString path)
	{
		path.replace("/", "\\");
		QDir dir(path);
		if (!dir.exists())
		{
			return true;
		}

		QFileInfoList fileList = dir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot, QDir::DirsFirst);
		foreach(QFileInfo file, fileList)
		{
			if (file.isDir())
			{
				removeDir(file.absoluteFilePath());
			}
			else if (file.isFile())
			{
				file.dir().remove(file.fileName());
			}
		}
		return dir.rmpath(dir.absolutePath());
	}

	bool FilePathUtils::removeFile(QString fileName)
	{
		fileName.replace("/", "\\");
		QFileInfo fileInfo(fileName);
		if (!fileInfo.isFile())
		{
			return true;
		}
		return QFile::remove(fileName);
	}

	bool FilePathUtils::rename(QString from, QString to)
	{
		from.replace("/", "\\");
		to.replace("/", "\\");
		return QFile::rename(from, to);
	}

	bool FilePathUtils::copyFile(QString from, QString to)
	{
		from.replace("/", "\\");
		to.replace("/", "\\");

		QFile file(from);
		QFileInfo fileInfo(file);
		QString dstFilePath;

		QDir dstDir(to);
		if (!dstDir.exists())
		{
			dstDir.mkpath(to);
		}

		dstFilePath = dstDir.filePath(fileInfo.fileName());
		QFile dstFile(dstFilePath);

		QString backupFilePath = dstFilePath + BACKUP_FILE_SUFFIX;
		QFile bakFile(backupFilePath);
		if (bakFile.exists())
		{
			// 瀛樺湪鍚嶄负**.bak
			bakFile.remove();
		}

		if (dstFile.exists())
		{
			// 瀛樺湪鍚屽悕鏂囦欢锛岄噸鍛藉悕涓?*.bak
			dstFile.rename(backupFilePath);
		}

		if (file.copy(dstFilePath))
		{
			// 澶嶅埗鎴愬姛锛屽皢bak鏂囦欢鍒犻櫎
			bakFile.remove();
			return true;
		}
		else
		{
			// 澶嶅埗澶辫触锛屽皢bak鏂囦欢杩樺師
			bakFile.rename(dstFilePath);
			return false;
		}
	}

	bool FilePathUtils::copyDir(QString oldPath, QString newPath, const bool &overwriteFile)
	{
		oldPath.replace("/", "\\");
		newPath.replace("/", "\\");

		QDir srcDir(oldPath);
		if (!srcDir.exists())
		{
			return false;
		}

		QDir dstDir(newPath);
		if (!dstDir.exists() && !dstDir.mkpath(newPath))
		{
			return false;
		}

		bool bRet = true;
		QFileInfoList fileInfoList = srcDir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot | QDir::Hidden, QDir::Name);

		foreach(QFileInfo fileInfo, fileInfoList)
		{
			if (fileInfo.isFile() || fileInfo.isSymLink())
			{
				//褰撳厑璁歌鐩栨搷浣滄椂锛屽皢鏃ф枃浠惰繘琛屽垹闄ゆ搷浣?
				if (overwriteFile && dstDir.exists(fileInfo.fileName()))
				{
					dstDir.remove(fileInfo.fileName());
				}

				if (!QFile::copy(fileInfo.filePath(), dstDir.filePath(fileInfo.fileName())))
				{
					bRet = false;
				}
			}
			else if (fileInfo.isDir())
			{
				QString dstFilePath = dstDir.filePath(fileInfo.fileName());
				QDir dstDir(dstFilePath);
				dstDir.mkpath(dstFilePath);

				if (!copyDir(fileInfo.filePath(), dstFilePath, overwriteFile))
				{
					bRet = false;
				}
			}
		}
		return bRet;
	}

	bool FilePathUtils::createDir(QString path)
	{
		path.replace("/", "\\");
		QDir dir;
		return dir.mkpath(path);
	}

	QString FilePathUtils::parentDir(QString path)
	{
		path.replace("/", "\\");
		QFileInfo fileinfo(path);
		if (fileinfo.isDir())
		{
			// cdUp 绛夋晥浜?cd ..鎿嶄綔
			bool state = fileinfo.dir().cdUp();
			if (state)
			{
				return  fileinfo.dir().path();
			}
		}
		else if (fileinfo.isFile())
		{
			QString tempPath = fileinfo.path();
			QDir dir(tempPath);
			if (dir.cdUp())
			{
				return dir.path();
			}
		}
		return QString();
	}

	QString FilePathUtils::path(QString path)
	{
		path.replace("/", "\\");
		QFileInfo fileinfo(path);
		return fileinfo.path();
	}

	QString FilePathUtils::suffix(QString path)
	{
		path.replace("/", "\\");
		QFileInfo fileinfo(path);
		return fileinfo.suffix();
	}

	QString FilePathUtils::baseName(QString path)
	{
		path.replace("/", "\\");
		QFileInfo fileinfo(path);
		return fileinfo.baseName();
	}

	QString FilePathUtils::fileName(QString path)
	{
		path.replace("/", "\\");
		QFileInfo fileinfo(path);
		return fileinfo.fileName();
	}

	QString FilePathUtils::changeSuffix(QString path, QString newExtension)
	{
		path.replace("/", "\\");
		QFileInfo fileInfo(path);
		if (!fileInfo.isFile())
		{
			return  QString();
		}

		QString newFilePath = QDir::fromNativeSeparators(fileInfo.path()) + QString("/") + fileInfo.baseName() + QString(".") + newExtension;
		return newFilePath;
	}

	void FilePathUtils::getAllSons(QString path, QVector<QString> &sons)
	{
		path.replace("/", "\\");
		QDir dir(path);
		if (!dir.exists())
		{
			return;
		}

		QFileInfoList fileInfoList = dir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot | QDir::Dirs);
		foreach(QFileInfo fileInfo, fileInfoList)
		{
			if (fileInfo.isFile())
			{
				sons.append(fileInfo.fileName());
			}
			else
			{
				getAllSons(fileInfo.absoluteFilePath(), sons);
			}
		}
		return;
	}

}// namespace Common
